//TIleForwardLightCullCSFX.h
//Created 30/09/13
//Created By Daniel Bowler
//
//Effect that will be used to preform the light culling stage in the Tile Based
//Forward Renderer. Only accessable within the GraphicsManager class to avoid people
//f*cking up things!

#pragma once

//We will inherit from the AbstractComputeFX (Rather than just the 
//AbstractCompute) because this is a compute shader effect.
#include "AbstractComputeFX.h"

//To get access to the #define that decides if we are going to write
//to a third texture (UAV) which tells us the maximum Z value for each tile. We can, for example,
//disable the function that sets the UAV (compile time) when it is disabled.
#include "GraphicsManager.h"

class TileForwardLightCullCSFX : public AbstractComputeFX
{
	//Shader Manager will create and manage an instance of this effect. The programmer
	//(In this case, the programmer who is developing the GraphicsManager) will ask
	//the shader manager to return a pointer to this effect.
	friend ShaderManager;
public:
	//Functions to set data. Eg, the UAVs, SRVs and Constant Buffers.
	//
	//Sets cbPerResize - Called whenever a resize event occuts. Passes the 
	//render targets height and width.
	void SetOnResizeCBuffer(float newWidth, float newHeight);
	//Sets per frame cbuffer
	void SetPerFrameCBuffer(CXMMATRIX& invProj, CXMMATRIX& view);
	//Sets light data
	void SetLightData(unsigned lightCount);

	//Sets Input depth texture - Check if the depth buffer was created with
	//msaa enabled (It will be if the gloabal (graphics manager) MSAA is true)
	void SetInputDepthTexture(ID3D11ShaderResourceView* depthTex, bool isMSAATex);
	//Sets LLB - Set whenever a new LLB is allocated/created
	void SetLightListBuffer(ID3D11ShaderResourceView* llb);
	//Sets the LLIB UAV - (output)
	void SetLightListIndexBufferOutput(ID3D11UnorderedAccessView* llibOut);
	//Sets the LLSEB UAV - (output)
	void SetLightListStartEndBufferOutput(ID3D11UnorderedAccessView* llsebOut);
	//Sets max z tile buffer. 
	void SetMaxZTileBuffer(ID3D11UnorderedAccessView* maxZTileBuffer);

	//Sets input data for the transparant tile
	void SetLightListIndexBufferTransparantOutput(ID3D11UnorderedAccessView* llibtOut);
	void SetLightListStartEndBufferTransparantOutput(ID3D11UnorderedAccessView* llsebtOut);

private:
	//We dont want the user to directly create one of these (They work with
	//pointers), so hide the constructor/destructors. 
	TileForwardLightCullCSFX(ID3D11Device* device);
	~TileForwardLightCullCSFX();
	//Disable the copy constructor and the = operator
	TileForwardLightCullCSFX(const TileForwardLightCullCSFX& other);
	TileForwardLightCullCSFX& operator = (const TileForwardLightCullCSFX& other);

	//Override this to aid in creating the FX class properly.
	void InitShaderVariablePointers();
private:
	//Shader Variables
	//
	//Input/Output Textures and Buffers
	//
	//Z Pre pass Input and MSAA variant (one or the other)
	ID3DX11EffectShaderResourceVariable* zPrePassBufferVar;
	ID3DX11EffectShaderResourceVariable* zPrePassBufferMSAAVar;
	//LLB - Light List Buffer (Structured)
	ID3DX11EffectShaderResourceVariable* llbVar;
	//UAV (Read-Write buffers/textures - Output): LLIB - Light List Index Buffer (uint)
	ID3DX11EffectUnorderedAccessViewVariable* llibVar;
	//LLSEB - Light list Start End Buffer - UAV (uint2)
	ID3DX11EffectUnorderedAccessViewVariable* llsebVar;
	//Per tile. Each entry represents the max z value out
	//of every pixel that shares that tile. 
	ID3DX11EffectUnorderedAccessViewVariable* maxZTileBuffVar;
	//
	//CBuffer data
	//
	//On Resize
	ID3DX11EffectScalarVariable* renderTargetWidthVar;
	ID3DX11EffectScalarVariable* renderTargetHeightVar;
	//Per Frame
	ID3DX11EffectMatrixVariable* invProjectionVar;
	ID3DX11EffectMatrixVariable* viewVar;
	//List list data
	ID3DX11EffectScalarVariable* numLightVar;
	//
	//Lighting UAVs for the transparant tiles - Suffexed by T
	//
	//Light List Index Buffer Transparant (LLIBT)
	ID3DX11EffectUnorderedAccessViewVariable* llibtVar;
	//Light List Start End Buffer Transparant (LLSEBT)
	ID3DX11EffectUnorderedAccessViewVariable* llsebtVar;
};